# 使用提醒:
# 1. xbot包提供软件自动化、数据表格、Excel、日志、AI等功能
# 2. package包提供访问当前应用数据的功能，如获取元素、访问全局变量、获取资源文件等功能
# 3. 当此模块作为流程独立运行时执行main函数
# 4. 可视化流程中可以通过"调用模块"的指令使用此模块

# ___ጿ ኈ ቼ ዽ ጿ   2025年5月15日 12:27:52   ጿ ኈ ቼ ዽ ጿ___
# 影刀RPA：https://www.yingdao.com/
# By GuoKe ：https://www.yingdao.com/community/userCenter?userUuid=687223449269694466
# 需安装库Pillow  pyperclip  numpy

import xbot
from xbot import print, sleep
from .import package
from .package import variables as glv
import os
import time
from PIL import Image, ImageDraw, ImageFont
import pyperclip
from io import BytesIO
import numpy as np

try:
    from xbot.app.logging import trace as print
except:
    pass

from typing import *

def list_to_image(data, save_path=None, to_clipboard=False, filename=None, beautify=False):

    # 验证输入
    if not isinstance(data, list):
        raise TypeError("输入数据必须是列表类型")
    
    # 处理保存路径
    if save_path is None:
        save_path = os.getcwd()  # 如果未提供路径，使用当前目录
    
    # 确保save_path是目录
    if os.path.isfile(save_path):
        save_dir = os.path.dirname(save_path)
    else:
        save_dir = save_path
    
    # 创建目录
    if save_dir and not os.path.exists(save_dir):
        os.makedirs(save_dir)
    
    # 生成完整的文件路径
    if filename:
        # 检查文件名是否包含扩展名，如果没有则添加 .png
        if not filename.lower().endswith('.png'):
            filename += '.png'
        full_path = os.path.join(save_dir, filename)
    else:
        # 生成带时间戳的文件名
        timestamp = time.strftime("%Y%m%d_%H%M%S")
        filename = f"list_{timestamp}.png"
        full_path = os.path.join(save_dir, filename)
    
    # 创建表格图片
    img = _create_table_image(data, beautify=beautify)
    
    # 保存图片
    img.save(full_path)
    
    # 如果需要，复制到剪贴板
    if to_clipboard:
        _copy_to_clipboard(img)
    
    return full_path

def _get_font():
    """获取支持中文的字体"""
    try:
        # 尝试使用系统字体
        font_paths = [
            # Windows 字体
            "C:/Windows/Fonts/simhei.ttf",  # 黑体
            "C:/Windows/Fonts/simsun.ttc",  # 宋体
            "C:/Windows/Fonts/msyh.ttc",    # 微软雅黑
            # macOS 字体
            "/System/Library/Fonts/PingFang.ttc",
            # Linux 字体
            "/usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf",
        ]
        
        for path in font_paths:
            if os.path.exists(path):
                return ImageFont.truetype(path, 14)
        
        # 如果找不到系统字体，使用默认字体
        return ImageFont.load_default()
    except Exception:
        return ImageFont.load_default()

def _create_table_image(data, beautify=False):
    """创建Excel表格样式的图片"""
    # 初始化参数
    cell_padding = 10
    min_cell_width = 80
    min_cell_height = 30
    max_cell_width = 300
    header_bg_color = (200, 200, 255)  # 表头背景色
    row_bg_color_even = (255, 255, 255)  # 偶数行背景色
    row_bg_color_odd = (240, 240, 240)   # 奇数行背景色
    border_color = (150, 150, 150)      # 边框颜色
    font = _get_font()
    
    # 处理空列表
    if not data or len(data) == 0:
        data = [["空数据"]]
    
    # 确保所有行的长度一致
    max_cols = max(len(row) if isinstance(row, list) else 1 for row in data)
    normalized_data = []
    for row in data:
        if not isinstance(row, list):
            normalized_data.append([row] + [""] * (max_cols - 1))
        else:
            normalized_data.append(row + [""] * (max_cols - len(row)))
    
    data = normalized_data
    
    # 计算每列的最大宽度
    col_widths = [0] * max_cols
    for row in data:
        for i, cell in enumerate(row):
            cell_str = str(cell)
            # 计算每个单元格的文本宽度
            try:
                width = font.getlength(cell_str)  # 新版PIL
            except AttributeError:
                width = font.getsize(cell_str)[0]  # 旧版PIL
            col_widths[i] = max(col_widths[i], min(max_cell_width, max(min_cell_width, width + cell_padding * 2)))
    
    # 计算每个单元格的内容换行情况和高度
    cell_heights = []
    wrapped_data = []
    
    for row in data:
        row_height = min_cell_height
        wrapped_row = []
        
        for i, cell in enumerate(row):
            cell_str = str(cell)
            
            # 如果内容宽度超过列宽，需要换行处理
            try:
                text_width = font.getlength(cell_str)  # 新版PIL
            except AttributeError:
                text_width = font.getsize(cell_str)[0]  # 旧版PIL
                
            available_width = col_widths[i] - cell_padding * 2
            
            if text_width <= available_width:
                wrapped_cell = [cell_str]
            else:
                # 简单的文本换行实现
                wrapped_cell = []
                current_line = ""
                
                for char in cell_str:
                    test_line = current_line + char
                    try:
                        test_width = font.getlength(test_line)  # 新版PIL
                    except AttributeError:
                        test_width = font.getsize(test_line)[0]  # 旧版PIL
                        
                    if test_width <= available_width:
                        current_line = test_line
                    else:
                        wrapped_cell.append(current_line)
                        current_line = char
                
                if current_line:
                    wrapped_cell.append(current_line)
            
            wrapped_row.append(wrapped_cell)
            # 计算单元格高度 = 行数 * 行高 + 上下填充
            cell_height = len(wrapped_cell) * 20 + cell_padding * 2
            row_height = max(row_height, cell_height)
        
        cell_heights.append(row_height)
        wrapped_data.append(wrapped_row)
    
    # 计算表格总宽度和高度
    table_width = sum(col_widths)
    table_height = sum(cell_heights)
    
    # 创建图片
    img = Image.new("RGB", (table_width, table_height), color=(255, 255, 255))
    draw = ImageDraw.Draw(img)
    
    # 绘制表格
    y_offset = 0
    for row_idx, (row, row_height) in enumerate(zip(wrapped_data, cell_heights)):
        x_offset = 0
        
        # 设置背景颜色
        if beautify:
            bg_color = header_bg_color if row_idx == 0 else (row_bg_color_even if row_idx % 2 == 0 else row_bg_color_odd)
        else:
            bg_color = (255, 255, 255)  # 默认白色背景
        
        draw.rectangle([(0, y_offset), (table_width, y_offset + row_height)], fill=bg_color)
        
        for col_idx, (wrapped_cell, col_width) in enumerate(zip(row, col_widths)):
            # 绘制单元格边框
            if beautify:
                draw.rectangle(
                    [(x_offset, y_offset), (x_offset + col_width, y_offset + row_height)], 
                    outline=border_color
                )
            else:
                draw.line([(x_offset, y_offset), (x_offset, y_offset + row_height)], fill=(0, 0, 0))  # 左侧边框
                draw.line([(x_offset, y_offset), (x_offset + col_width, y_offset)], fill=(0, 0, 0))  # 上方边框
                draw.line([(x_offset + col_width, y_offset), (x_offset + col_width, y_offset + row_height)], fill=(0, 0, 0))  # 右侧边框
                draw.line([(x_offset, y_offset + row_height), (x_offset + col_width, y_offset + row_height)], fill=(0, 0, 0))  # 下方边框
            
            # 绘制单元格内容（居中）
            cell_content_height = len(wrapped_cell) * 20
            text_y_start = y_offset + (row_height - cell_content_height) // 2
            
            for line_idx, line in enumerate(wrapped_cell):
                try:
                    line_width = font.getlength(line)  # 新版PIL
                except AttributeError:
                    line_width = font.getsize(line)[0]  # 旧版PIL
                
                text_x = x_offset + (col_width - line_width) // 2
                text_y = text_y_start + line_idx * 20
                
                draw.text((text_x, text_y), line, fill=(0, 0, 0), font=font)
            
            x_offset += col_width
        
        y_offset += row_height
    
    return img

def _copy_to_clipboard(img):
    """将图片复制到剪贴板"""
    try:
        # Windows系统
        import win32clipboard
        output = BytesIO()
        img.convert('RGB').save(output, 'BMP')
        data = output.getvalue()[14:]
        output.close()
        
        win32clipboard.OpenClipboard()
        win32clipboard.EmptyClipboard()
        win32clipboard.SetClipboardData(win32clipboard.CF_DIB, data)
        win32clipboard.CloseClipboard()
        return True
    except ImportError:
        pass
    
    try:
        # macOS系统
        import subprocess
        buffer = BytesIO()
        img.save(buffer, 'PNG')
        process = subprocess.Popen(['pbcopy', '-Pngboard'], stdin=subprocess.PIPE)
        process.communicate(buffer.getvalue())
        buffer.close()
        return True
    except Exception:
        pass
    
    # 如果上述方法都失败，则只能清空剪贴板
    pyperclip.copy("")
    return False



